package controller;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import model.Afd;
import model.State;
import model.Symbol;
import model.Transition;

public class AfdController {
	private static final String FILE_NAME = "afd.conf";
	private Afd afd;
	private static AfdController afdController;
	
	private AfdController(){
	}
	
	public static AfdController getInstance(){
		if(afdController == null){
			afdController = new AfdController();
		}
		return afdController;
	}
	
	public void saveAfd(String states, int numFinalStates, String symbols,
			String transitions, int firstStateIsFinal) {
		ArrayList<State> afdStates = new ArrayList<State>();
		for (String s : states.split(" ")) {
			State afdState = new State(s.charAt(0));
			afdStates.add(afdState);
		}
		
		ArrayList<State> finalStates = new ArrayList<State>();
		for (int i = 1; i <= numFinalStates; i++) {
			finalStates.add(afdStates.get(i - firstStateIsFinal));
		}
		
		ArrayList<Symbol> afdSymbols = new ArrayList<Symbol>();
		for (String s : symbols.split(" ")) {
			Symbol afdSymbol = new Symbol(s.charAt(0));
			afdSymbols.add(afdSymbol);
		}
		ArrayList<Transition> afdTransitions = new ArrayList<Transition>();
		for (String s : transitions.split(" ")) {
			State initialState = getState(afdStates, s.split("x|-")[0].charAt(0));
			State finalState = getState(afdStates, s.split("x|-")[2].charAt(0));
			Symbol symbol = getSymbol(afdSymbols, s.split("x|-")[1].charAt(0));
			Transition transition = new Transition(initialState, finalState, symbol);
			afdTransitions.add(transition);
		}
		setAfd(new Afd(afdStates, afdSymbols, afdTransitions, afdStates.get(0), finalStates));
	}

	
	
	private Symbol getSymbol(ArrayList<Symbol> afdSymbols, char symbol) {
		for (Symbol afdSsymbol : afdSymbols) {
			if(afdSsymbol.getSymbol() == symbol){
				return afdSsymbol;
			}
		}
		return null;
	}



	private State getState(ArrayList<State> afdStates, char symbol) {
		for (State state : afdStates) {
			if(state.getSymbol() == symbol)
				return state;
		}
		return null;
	}



	public void setAfd(Afd afd) {
		this.afd = afd;
	}


	public Afd getAfd() {
		return afd;
	}

	public void saveAfdIntoTheFile() throws IOException {
		FileOutputStream fos = new FileOutputStream(FILE_NAME);
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(afd);
		oos.close();
	}

	public void loadAfdFromFile() throws IOException, ClassNotFoundException {
		FileInputStream fos = new FileInputStream(FILE_NAME);
		ObjectInputStream oos = new ObjectInputStream(fos);
		afd = (Afd) oos.readObject();
		oos.close();
	}	
}
